home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
PRINTING
/
LPT123
/
LPT123.PAS
next >
Wrap
Pascal/Delphi Source File
|
1988-12-09
|
7KB
|
196 lines
{$S-,I-,V-,E-}
UNIT LPT123;
{
MODULE: LPT123.PAS
AUTHOR: L. Christopher Luther, ProLogic Consultants
DATE: December 1, 1988
PURPOSE: The purpose of this Unit is to provide a generic printer
interface for all Turbo Pascal 5.0 (and 4.0 if you remove the
E- compiler directive) programs. I feel that it fills a few
gaps that Borland forgot to include in their Printer Unit.
Two of the routines, Eject_A_Page and PrinterStatus, were
obtained from the last issue of the Turbo User's Group Magazine,
"TUG Lines." Eject_A_Page is sooooo simple that I could not
improve it. However, PrinterStatus did not load the number of
the printer into register DX. As a result, the routine was not
consistent in its operation. I modified it around the other
functions that I wrote so that it will report the status of
whichever printer port is currently open.
I hope that this routine is the first step to others sharing
their code. I welcome comments and improvements. Maybe someone
could write a set BIOS routines to make the LST output faster.
}
{=============================================================================}
INTERFACE
CONST
PrtNoError = 0; { No printer error detected }
PrtInUse = 1; { Printer busy error }
PrtNotSelected = 2; { Printer not on line error }
PrtNoPaper = 3; { Printer out of paper error }
PrtNoPower = 4; { Printer no power error }
PrtMiscError = 5; { Unknown printer error }
VAR
Lst : TEXT;
PROCEDURE SetLstMode (Raw : BOOLEAN); { Toggle Cooked/Raw mode for Lst }
PROCEDURE AssignLst (LstPort : BYTE); { Open LPT1: through LPT3: }
PROCEDURE Eject_a_Page; { Send a form feed to Lst }
FUNCTION PrinterStatus : INTEGER; { Attempt to determine Lst status }
{=============================================================================}
IMPLEMENTATION
USES
DOS;
CONST
FirstTime : BOOLEAN = TRUE; { A simple switch (see AssignLst). }
VAR
Regs : REGISTERS; { We need these registers. }
ExitSave : POINTER; { Pointer to old Exit Proc. }
OldLstMode : BOOLEAN; { Old status of Lst Raw or Cooked. }
LstFileHandle : WORD Absolute Lst; { The file handle for the LST Text }
{ Device Driver. }
{*****************************************************************************}
FUNCTION GetLstMode : BOOLEAN;
BEGIN
WITH Regs DO
BEGIN
AX := $4400; { Get device status }
BX := LstFileHandle; { Lst device handle }
MSDOS (Regs); { Call INT 21 Function }
GetLstMode := Odd(DX Shr 5); { Get the current status }
END; { of the Raw Bit }
END;
{*****************************************************************************}
PROCEDURE SetLstMode (Raw : BOOLEAN);
BEGIN
WITH Regs DO
BEGIN
AX := $4400; { Get device status }
BX := LstFileHandle; { Lst device handle }
MSDOS (Regs); { Call INT 21 Function }
AX := $4401; { Set device status }
DX := DX AND $00DF; { Clear the Raw Bit }
IF Raw THEN
Inc (DX, 32);
MSDOS (Regs); { Call INT 21 Function }
END;
END;
{*****************************************************************************}
{$F+}
PROCEDURE ExitHandler;
BEGIN
ExitProc := ExitSave; { Restore old Exit Proc Pointer. }
SetLstMode (OldLstMode); { Restore Lst to its old status. }
Close (Lst); { Close the LST Text Device Driver. }
END;
{$F-}
{*****************************************************************************}
PROCEDURE AssignLst (LstPort : BYTE);
VAR
LptName : STRING[4];
DummyErr : WORD;
BEGIN
IF NOT FirstTime THEN { If this is not the first time that }
BEGIN { the routine is executed, then }
SetLstMode (OldLstMode); { restore the Raw/Cooked status of }
Close (Lst); { LPT? and close the device. }
DummyErr := IOResult; { We do not care if any IO Errors }
END { occur. }
ELSE
FirstTime := FALSE;
CASE LstPort OF
1 : LptName := 'LPT1';
2 : LptName := 'LPT2';
3 : LptName := 'LPT3';
ELSE
LptName := 'LPT1'; { Default to LPT1 if invalid port }
END;
Assign (Lst, LptName);
WITH TextRec(Lst) DO
BEGIN
CASE LstPort OF
1 : UserData[1] := 0; { Store the LPT port in UserData[1] }
{ DOS uses 0 for LPT1: }
2 : UserData[1] := 1; { Store the LPT port in UserData[1] }
{ DOS uses 1 for LPT2: }
3 : UserData[1] := 2; { Store the LPT port in UserData[1] }
{ DOS uses 2 for LPT3: }
ELSE
UserData[1] := 0; { Store the LPT port in UserData[1] }
{ DOS uses 0 for LPT1: }
END;
END;
ReWrite (Lst); { Open the LST Text Device Driver. }
DummyErr := IOResult; { We do not care what errors occur. }
OldLstMode := GetLstMode; { Save the Raw/Cooked Status of LST. }
END;
{*****************************************************************************}
PROCEDURE Eject_a_Page;
CONST
FormFeed = #12;
BEGIN
Write (Lst, FormFeed); { Real simple, Eject one page }
END;
{*****************************************************************************}
FUNCTION PrinterStatus : INTEGER;
{ See the DOS technical Reference for the values of the Bits that are set
in register AH by this function. }
BEGIN
WITH Regs DO
BEGIN
AH := $02; { Printer status function code. }
DX := TextRec(Lst).UserData[1];
Intr ($17, Regs); { Printer service interrupt. }
CASE AH OF
$90 : PrinterStatus := PrtNoError;
$A1 : PrinterStatus := PrtInUse;
$08 : PrinterStatus := PrtNotSelected;
$28 : PrinterStatus := PrtNoPaper;
$48 : PrinterStatus := PrtNoPower; { for IBM XT }
ELSE
PrinterStatus := PrtMiscError;
END;
END;
END;
{=============================================================================}
{ Unit INITIALIZATION }
BEGIN
AssignLst (1); { Open LST as LPT1: }
ExitSave := ExitProc; { Save the current Exit Proc.}
ExitProc := @ExitHandler { Install our own Exit Proc. }
END.